package org.naxx.security.function.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;

import org.apache.log4j.Logger;
import org.naxx.security.function.FunctionType;
import org.naxx.security.function.FunctionTypeDefinitionLoader;
import org.naxx.security.parser.funcdef.FunctionTypeDefinitionParser;
import org.naxx.security.util.FileSystemUtil;

public class FunctionTypeDefinitionLoaderImpl implements
		FunctionTypeDefinitionLoader {
	
	private static final Logger logger = Logger
			.getLogger(FunctionTypeDefinitionLoaderImpl.class);
	
	private String[] functionDefinitionsFileNames;
	private FunctionTypeDefinitionParser functionTypeDefinitionParser;
	
	public void setFunctionTypeDefinitionParser(
			FunctionTypeDefinitionParser functionTypeDefinitionParser) {
		this.functionTypeDefinitionParser = functionTypeDefinitionParser;
	}

	public void setFunctionDefinitionsFileNames(
			String[] functionDefinitionsFileNames) {
		this.functionDefinitionsFileNames = functionDefinitionsFileNames;
	}

	public Set<FunctionType> loadFunctionDefinitions() {
		final Set<FunctionType> result = new HashSet<FunctionType>();
		for (int i = 0; i < this.functionDefinitionsFileNames.length; i++) {
			result.addAll(this.loadFunctionDefinitions(this.functionDefinitionsFileNames[i]));
		}
		return result;
	}
	
	public Set<FunctionType> loadFunctionDefinitions(String fileName) {
		logger.info("Loading function definitions from file '" + fileName + "'");
		InputStream in = null;
		XMLEventReader reader = null;
		try {
			in = new FileInputStream(fileName);
			reader = XMLInputFactory.newInstance().createXMLEventReader(in);
			this.functionTypeDefinitionParser.skipDocumentStart(reader);
			Set<FunctionType> functionTypes = this.functionTypeDefinitionParser.parse(reader);
			logger.info("Loaded '" + (functionTypes == null ? 0 : functionTypes.size()) + "'" +
					" function types from file '" + fileName + "'");
			return functionTypes;
		} catch(Exception e) {
			throw new IllegalStateException(e);
		} finally {
			FileSystemUtil.release(reader);
			FileSystemUtil.close(in);
		}
	}
}
